import {
  Component,
  ElementRef,
  inject,
  Input,
  OnChanges,
  OnDestroy,
  OnInit,
  SimpleChanges,
  ViewChild
} from '@angular/core';
import {Graph, Node } from '@antv/x6';
import {VirtualLoopData} from '../../models/svgdata';
import {LoopdataService} from '../../services/loopdata.service';
import {drawConfigType} from '../types/draw-config.type';
import {customShapeRegister, heightCompute, render, softStrapShapeRegister} from '../tools/draw-antv-graph';

@Component({
  selector: 'app-antv-graph',
  standalone: false,
  templateUrl: './antv-graph.component.html',
  styleUrl: './antv-graph.component.css'
})
export class AntvGraphComponent implements OnInit, OnChanges, OnDestroy  {
  @Input() dataType!: number;
  @ViewChild('graphContainer', { static: true }) graphContainer!: ElementRef;
  private loopDataService = inject(LoopdataService);
  private graph!: Graph;
  private data!: VirtualLoopData;

  private canvasSize: {width: number; height: number} = {width: 1015, height: 0};
  private moduleSize : {width: number; height: number} = {width: 220, height: 0};

  private shapeSoftStrapMap = new Map<string, string[]>();
  private loopBranchVisibilityMap = new Map<string, boolean>();

  private drawDefaultConfig: drawConfigType = {
    baseDrawConfig: {
      moduleDistance: 700,
      font: {
        small: 8,
        normal: 11,
      },
      color: {
        primary: '#00367a',
        moduleBorderColor: '#27cef7',
        accent: '#25ccf7',
        text: '#ffffff',
        dashedLine: '#000000',
      }
    },
    loopBranchConfig: {
      lineColor: '#25ccf7',
      textColor: '#ffffff',
      textSize: 8,
      lineDistance: 700,
    }
  }


  private drawProps = {
    drawConfig: this.drawDefaultConfig,
    moduleSize: this.moduleSize
  }

  ngOnInit(){
    this.loadData(this.dataType)
    softStrapShapeRegister()
    customShapeRegister()
  }

  ngOnChanges(changes: SimpleChanges){
    this.loadData(changes['dataType'].currentValue);
  }

  ngOnDestroy() {
    if (this.graph) {
      this.graph.dispose();
    }
  }

  private renderGraph() {
    if (this.data && this.graphContainer) {
      this.graphContainer.nativeElement.innerHTML = '';
      // 清空之前的状态映射
      this.shapeSoftStrapMap.clear();
      this.loopBranchVisibilityMap.clear();
      if (this.graph) {
        this.graph.dispose();
      }
      this.initGraph()
      render(this.graph, this.data,  this.canvasSize, this.moduleSize,this.shapeSoftStrapMap,this.loopBranchVisibilityMap, this.drawProps)
    }
  }

  loadData(dataType: number) {
    this.loopDataService.getLoopData(dataType).subscribe({
      next: (data) => {
        this.data = data;
        this.moduleSize.height = heightCompute(data);
        this.canvasSize.height = this.moduleSize.height + 100;
        console.time('antv x6 render')
        this.renderGraph();
        console.timeEnd('antv x6 render')
      },
      error: (err) => {
        console.error('数据加载失败',err);
      }
    })
  }

  private initGraph() {
    const rect = this.graphContainer.nativeElement.getBoundingClientRect();
    this.graph = new Graph({
      container: this.graphContainer.nativeElement,
      width: rect.width,
      height: rect.height,
      panning: true,
      mousewheel: {
        enabled: true,
        factor: 1.05
      },
      scaling: {
        min: 0.2,
        max: 3
      },
      interacting: {
        nodeMovable: false // 禁用节点移动
      },
    });

    this.setupNodeEventListeners();

  }

  private setupNodeEventListeners() {
    this.graph.on('node:click', ({ cell, e, view }) => {
      e.stopPropagation()
      const node = cell as Node;
      const target = e.target as SVGElement;
      let selector = target.getAttribute('selector')

      console.log(selector)
      if (selector === 'arrowHead') {
        const targetNode = this.graph.getCellById(node.id) as Node;
        if (!targetNode) return;
        this.loopBranchVisibilityMap.set(node.id, !this.loopBranchVisibilityMap.get(node.id));
        const isVisible = this.loopBranchVisibilityMap.get(node.id);
        const buttonText = isVisible ? '展开' : '收缩';
        console.log(node.id, isVisible ? 'visible' : 'hidden')

        // ***必须等视图更新完成之后设置才有效***
        setTimeout(() => {
          targetNode.attr('loopBranch/visibility', isVisible ? 'visible' : 'hidden');
          targetNode.attr('changeText/text', buttonText);
        }, 0);

        const relatedSoftStraps = this.shapeSoftStrapMap.get(node.id);
        if (relatedSoftStraps) {
          relatedSoftStraps.forEach(softStrapId => {
            const softStrapNode = this.graph.getCellById(softStrapId) as Node;
            if (softStrapNode) {
              if (isVisible) {
                softStrapNode.show();
              } else {
                softStrapNode.hide();
              }
            }
          });
        }
      }
    })
  }

}
